from direct.task import Task 
from panda3d.core import *
from panda3d.bullet import *
from random import randint, random
from kcc import PandaBulletCharacterController
from direct.gui.DirectGui import *

# Setup our physics world
class Physics():
    def __init__(self):
            self.triggerlist = []
            self.OnLadder = 0
            # Scene
            self.world = BulletWorld()
            self.world.setGravity(Vec3(0, 0, -9.81))
            # Debug renderer
            debugNode = BulletDebugNode('Debug')
            debugNode.showWireframe(False)
            debugNode.showConstraints(False)
            debugNode.showBoundingBoxes(True)
            debugNode.showNormals(False)
            debugNP = render.attachNewNode(debugNode)
            self.world.setDebugNode(debugNP.node())
            #debugNP.show()
    def CreatePlayerPhysics(self):
        self.worldNP = render.attachNewNode('World')
        self.pController = PandaBulletCharacterController(self.world, self.worldNP, 1.7,1.2, 0.0, 0.5)

    def LoadMapPhysics(self,map):
        for geomNP in map.findAllMatches('**/+GeomNode'):
            geomNode = geomNP.node()
            if "Mesh" in geomNode.getName():
                mesh = BulletTriangleMesh()
                for geoms in range(geomNode.getNumGeoms()):
                    mesh.addGeom(geomNode.getGeom(geoms))
                mShape = BulletTriangleMeshShape(mesh, dynamic=False)
 
                node = BulletRigidBodyNode('Map-mesh')
                node.addShape(mShape)
 
                self.mController = render.attachNewNode(node)
                self.mController.setPos(0, 0, 0)
                self.mController.setHpr(0,180,0)
                self.world.attachRigidBody(node)
            if "Ladder" in geomNode.getName():
                min, max = geomNP.getTightBounds()
                centre = (min+max) * 0.5
                size = Vec3(max - min)/2
                if size.getX() > size.getY():
                    size=Vec3(size.getX(),size.getY()*4,size.getZ())
                else:
                    size=Vec3(size.getX()*4,size.getY(),size.getZ())
                mesh = BulletBoxShape(size)
                trigger = BulletGhostNode('Ladder')
                trigger.addShape(mesh)
                ladder = render.attachNewNode(trigger)
                ladder.setPos(Point3(centre.getX(),-centre.getY(),-centre.getZ()))
                self.triggerlist.append(ladder)
                self.world.attachGhost(trigger)
            #            if "Water" in geomNode.getName():
            #                print "water"
            #                geomNP.hide()
            #                #base.watermesh = geomNP
            #else:
            #    print "Failed Map Collisions."

    def cleanup(self):
        pass
    
    def Update(self,task):
            dt=globalClock.getDt()
            self.world.doPhysics(dt,100, 1./180.)
            self.pController.update()
            self.Triggers()
            return Task.cont
        
    def doRaycast(self,start,direction,length):
            pFrom = Point3(start)
            pTo = Point3(start+(direction*length))
            
            hit = self.world.rayTestClosest(pFrom, pTo)
            return hit
        
    def Triggers(self):
        self.OnLadder = 0
        for trigger in self.triggerlist:
            for node in trigger.node().getOverlappingNodes():
                if node.getName() == 'Map-mesh':
                    pass
                elif node.getName() == 'Capsule':
                    self.OnLadder = 1
                else:
                    print node.getName()


